package org.cloud.ext.websocket.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import org.cloud.ext.mq.common.MqConstants;
import org.cloud.ext.service.GroupService;
import org.cloud.ext.util.res.ApiResult;
import org.cloud.ext.websocket.common.WsConstants;
import org.cloud.ext.websocket.domain.GroupSession;
import org.cloud.ext.websocket.domain.OutMessage;
import org.cloud.ext.websocket.service.WsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.user.SimpUser;
import org.springframework.messaging.simp.user.SimpUserRegistry;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * @author xukk
 * @date 2020/3/10
 */
@Service
public class WsServiceImpl implements WsService {
    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;
    @Autowired
    private SimpUserRegistry userRegistry;
    @Autowired
    private GroupService groupService;

    @Override
    public ApiResult handleFromMq(JSONObject jsonObject) {
        String messageType=jsonObject.getString(MqConstants.ST.MESSAGE_TYPE);
        Integer respType = jsonObject.getInteger(MqConstants.ST.RESP_TYPE);
        String data = jsonObject.getString(MqConstants.ST.DATA);
        String pushWay = jsonObject.getString(MqConstants.ST.PUSH_WAY);
        String users = jsonObject.getString(MqConstants.ST.USER_LIST);
        String excludeUsers = jsonObject.getString(MqConstants.ST.EXCLUDE_USER_LIST);
        String groups = jsonObject.getString(MqConstants.ST.GROUP_LIST);
        String excludeGroups = jsonObject.getString(MqConstants.ST.EXCLUDE_GROUP_LIST);
        List<String> pushWayList = StringUtils.isEmpty(pushWay) ? Lists.newArrayList() : Splitter.on(",").trimResults().omitEmptyStrings().splitToList(pushWay);
        List<String> userList = StringUtils.isEmpty(users) ?
                Lists.newArrayList() : Splitter.on(",").trimResults().omitEmptyStrings().splitToList(users);
        List<String> excludeUserList = StringUtils.isEmpty(excludeUsers) ?
                Lists.newArrayList() : Splitter.on(",").trimResults().omitEmptyStrings().splitToList(excludeUsers);
        List<String> groupList = StringUtils.isEmpty(groups) ?
                Lists.newArrayList() : Splitter.on(",").trimResults().omitEmptyStrings().splitToList(groups);
        List<String> excludeGroupList = StringUtils.isEmpty(excludeGroups) ?
                Lists.newArrayList() : Splitter.on(",").trimResults().omitEmptyStrings().splitToList(excludeGroups);
        switch (respType) {
            case 0:
                // single
            case 1:
                // multi
                pushWayList.forEach(v -> userList.forEach(t -> {
                            String user = v + "_" + t;
                            user=user.toLowerCase();
                            SimpUser simpUser = userRegistry.getUser(user);
                            if (simpUser != null) {
                                simpMessagingTemplate.convertAndSendToUser(user, WsConstants.WS.BROKER_MESSAGE,
                                        OutMessage.builder()
                                                .content(data)
                                                .respType(respType)
                                                .messageType(messageType)
                                                .build());
                            }
                        }
                ));
                break;
            case 2:
                // broadcast
                simpMessagingTemplate.convertAndSend(WsConstants.WS.BROKER_MESSAGE_PUBLIC,
                        OutMessage.builder()
                                .content(data)
                                .respType(respType)
                                .messageType(messageType)
                                .build());
                break;
            case 3:
                //分组推
                pushWayList.forEach(p -> {
                    // 所有人员最小部门列表 A|B|C|D|E
                    //                   A|B|C|D|F|G
                    //                   A|B|C|D|F|H|I
                    Set<String> a = GroupSession.getGroup().keySet();
                    if (!CollectionUtils.isEmpty(a)) {
                        a.forEach(t -> {
                            if (groupService.checkGroupPush(p, t, groupList, excludeGroupList)) {
                                Set<String> b = GroupSession.getGroup().get(t);
                                if (!CollectionUtils.isEmpty(b)) {
                                    b.forEach(k -> {
                                        String k1=k.replace(p+"_","");
                                        if (!CollectionUtils.isEmpty(userList)) {
                                            if (userList.contains(k1)) {
                                                simpMessagingTemplate.convertAndSendToUser(k, WsConstants.WS.BROKER_MESSAGE,
                                                        OutMessage.builder()
                                                                .content(data)
                                                                .respType(respType)
                                                                .messageType(messageType)
                                                                .build());
                                            }
                                        }
                                        if (!CollectionUtils.isEmpty(excludeUserList)) {
                                            if (!excludeUserList.contains(k1)) {
                                                simpMessagingTemplate.convertAndSendToUser(k, WsConstants.WS.BROKER_MESSAGE,
                                                        OutMessage.builder()
                                                                .content(data)
                                                                .respType(respType)
                                                                .messageType(messageType)
                                                                .build());
                                            }
                                        }
                                        if (CollectionUtils.isEmpty(userList) && CollectionUtils.isEmpty(excludeUserList)) {
                                            simpMessagingTemplate.convertAndSendToUser(k, WsConstants.WS.BROKER_MESSAGE,
                                                    OutMessage.builder()
                                                            .content(data)
                                                            .respType(respType)
                                                            .messageType(messageType)
                                                            .build());
                                        }

                                    });

                                }

                            }
                        });
                    }
                });
                break;
            default:
                return ApiResult.renderError("缺少respType");
        }
        return ApiResult.renderOk();
    }
}
